﻿ <script setup>

import {dateFormat} from '@/util';
import {ElMessageBox} from "element-plus";

/**

 * records: 表格行数据

 * columns: 表格列数据

 *   type:

 *     tag:

 *       tagType: 标签颜色，默认 "warning"

 *       prefix: 前缀文字

 *       suffix: 后缀文字

 *       format: 前置格式化函数

 *     star:

 *     card:

 *       prefix: 前缀文字

 *       suffix: 后缀文字

 *       format: 前置格式化函数

 *     img:

 *       minio: MINIO地址前缀函数

 *     icon:

 *       iconType: 图标颜色，默认 "primary"

 *       iconSize: 图标尺寸，默认 "small"

 *     其他:

 *       prefix: 前缀文字

 *       suffix: 后缀文字

 *       format: 前置格式化函数

 *   column: 列名数组

 *   property: 属性名

 *   width: 列宽

 *   sortable: 是否支持排序，默认 true

 *   tooltip: 是否支持溢出内容的鼠标经过提示，默认 false

 * buttons:

 *   type:

 *     info: 详情按钮

 *     update: 修改按钮

 *     delete: 删除按钮

 *     upload: 上传按钮

 *       btnLabel: 按钮文案，默认 "上传文件"

 *     其他:

 *       btnLabel: 按钮文案，默认 "功能按钮"

 *       btnType: 按钮颜色，默认 "success"

 *       btnIcon: 按钮图标，默认 "InfoFilled"

 *   fn: 当点击按钮时触发的回调函数

 * selectionChange: 当勾选表格项时触发的回调函数

 */

let parent = defineProps({

  'records': {type: Array, required: true},

  'columns': {type: Array, required: true},

  'buttons': {type: Array, required: true},

  'selectionChange': {type: Function, required: false},

});



/* ==================== 处理表格多级标题 ==================== */



// 表格列数据对象

let columnsObj = {};



/*

 * 原格式:

 *

 * [

 *   {column: ['a', 'b'], property: 'id01'},

 *   {column: ['a', 'c'], property: 'id02'},

 *   {column: ['b', 'c'], property: 'id03'},

 * ]

 *

 * 新格式:

 *

 * {

 *   'a': [{column: 'b', property: 'id01'}, {column: 'c', property: 'id02'}],

 *   'b': [{column: 'c', property: 'id03'}],

 * }

 *

 */

for (let column of parent['columns']) {

  /*// '主键' -> ['主键']

  if (typeof column['column'] === 'string') {

    column['column'] = [column['column']]

  }

  // ['主键'] -> ['', '主键']

  if (column['column'].length === 1) {

    column['column'] = ['', column['column']];

  }*/
  if(typeof column['column'] === 'string' || column['column'].length === 1){
    column['column'] = ['基本信息', column['column']]
  }

  // 获取一级标题

  let parentName = column['column'][0];

  column['column'] = column['column'][1];

  // 若 columnsObj 中已经存在该一级标题对应的数组，则取出该数组，并加入该一级标题

  if (columnsObj.hasOwnProperty(parentName)) {

    columnsObj[parentName].push(column);

  }

  // 若 columnsObj 中不经存在该一级标题对应的数组，则创建新数组，再加入该一级标题

  else {

    columnsObj[parentName] = [column];

  }

}



/* ==================== 处理表格数据显示 ==================== */



/*

 * 原格式:

 *

 * row['user.username']

 *

 * 新格式:

 *

 * row['user']['username']

 *

 */

function toMustache(row, property) {

  // 'user.username' -> ['user', 'username']

  let propertiesArray = property.split('.');

  for (let i = 0, j = propertiesArray.length; i < j; i++) {

    // i=0: row = row['user']

    // i=1: row = row['user']['username']

    if(row) row = row[propertiesArray[i]];

  }

  return row;

}

function detail(row,property){
  ElMessageBox.alert(row[property], '记录详情', {
    confirmButtonText: '了解',
    callback: () => {

    },
  });
}

</script>



<template>

  <el-table class="my-table" tooltip-effect="light" stripe

            :data="records" @selection-change="selectionChange">

    <el-table-column class="head-col" label="序号" align="center" fixed="left">

      <el-table-column type="selection" width="40"/>

      <el-table-column type="index" width="40"/>

    </el-table-column>

    <el-table-column class="body-col" align="center"

                     v-for="(childrenArray, parentLabel) in columnsObj" :key="childrenArray"

                     :label="parentLabel">

      <el-table-column v-for="(item) in childrenArray" :key="item"

                       :label="item['column']"

                       :property="item['property']"

                       :width="item['width'] || (

                           item['type'] === 'card' ? 300 :

                           item['type'] === 'tag' ? 110 :

                           item['type'] === 'img' ? 110 : 200

                       )"

                       :sortable="item['sortable'] || true"

                       :show-overflow-toolti p="item['tooltip'] || false">

        <template #default="scope">



          <el-tag v-if="item['type'] === 'tag'"

                  :type="item['tagType'] || 'warning'">

            <span>{{ item['prefix'] }}</span>

            <span v-if="item['format']">{{ item['format'](toMustache(scope.row, item['property'])) }}</span>

            <span v-else>{{ toMustache(scope.row, item['property']) }}</span>

            <span>{{ item['suffix'] }}</span>

          </el-tag>



          <el-rate v-else-if="item['type'] === 'star'" disabled show-score

                   v-model="scope.row[item['property']]"

                   text-color="#ff9900" score-template="{value} 分"/>



          <el-card v-else-if="item['type'] === 'card'" @click="detail(scope.row, item['property'])">

            <span>{{ item['prefix'] }}</span>

            <span v-if="item['format']">{{ item['format'](toMustache(scope.row, item['property'])) }}</span>

            <span v-else>{{ toMustache(scope.row, item['property']) }}</span>

            <span>{{ item['suffix'] }}</span>

          </el-card>



          <!--preview-teleported用于解决图片Z轴遮挡问题-->

          <el-image v-else-if="item['type'] === 'img'" fit="fill" preview-teleported

                    :src="item['minio'](toMustache(scope.row, item['property']))"

                    :preview-src-list="[item['minio'](toMustache(scope.row, item['property']))]"/>



          <el-button v-else-if="item['type'] === 'icon'" plain

                     :type="item['iconType'] || 'primary'"

                     :size="item['iconSize'] || 'small'"

                     :icon="toMustache(scope.row, item['property'])">

          </el-button>



          <div v-else>

            <span>{{ item['prefix'] }}</span>

            <span v-if="item['format']">{{ item['format'](toMustache(scope.row, item['property'])) }}</span>

            <span v-else>{{ toMustache(scope.row, item['property']) }}</span>

            <span>{{ item['suffix'] }}</span>

          </div>



        </template>

      </el-table-column>

    </el-table-column>

    <el-table-column class="time-col" label="时间信息" align="center">

      <el-table-column label="创建时间" property="created" :width="200" sortable

                       :formatter="row => dateFormat(row['created'])"/>

      <el-table-column label="修改时间" property="updated" :width="200" sortable

                       :formatter="row => dateFormat(row['updated'])"/>

    </el-table-column>

    <el-table-column class="foot-col" label="操作区" align="center" fixed="right"

                     :width="170">

      <template #default="scope">

        <div class="foot-col-inner">

     <span v-for="(button, i) in buttons" :key="button">



       <el-button class="info-btn" v-if="button['type'] === 'info'" link size="small"

                  type="info" icon="InfoFilled"

                  @click="button['fn'](scope.row)">

         查看详情

       </el-button>



       <el-button class="update-btn" v-else-if="button['type'] === 'update'" link size="small"

                  type="warning" icon="Edit"

                  @click="button['fn'](scope.row)">

         修改记录

       </el-button>



       <el-button class="delete-btn" v-else-if="button['type'] === 'delete'" link size="small"

                  type="danger" icon="Delete"

                  @click="button['fn'](scope.row)">

         删除记录

       </el-button>



       <el-button class="upload-btn" v-else-if="button['type'] === 'upload'" link size="small"

                  type="primary" icon="UploadFilled"

                  @click="button['fn'](scope.row)">

         {{ button['btnLabel'] || '上传文件' }}

       </el-button>



       <el-button v-else link size="small"

                  :type="button['btnType'] || 'success'"

                  :icon="button['btnIcon'] || 'InfoFilled'"

                  @click="button['fn'](scope.row)">

         {{ button['btnLabel'] || '功能按钮' }}

       </el-button>



       <!--逢2换行-->

       <br v-if="i % 2 === 1"/>

     </span>

        </div>

      </template>

    </el-table-column>



    <!--用于调控表格宽度-->

    <el-table-column/>



  </el-table>

</template>



<style scoped lang="scss">

.my-table {

  height: 500px; // 高度



  .el-image {

    width: 84px; // 宽度

    height: 50px; // 高度

  }

}



.foot-col-btn {

  margin: 0 1px; // 外边距

}



.foot-col-inner {

  text-align: left; // 居左

}

.el-card {
  max-height: 61px; // 最大高度（不超过3行）
  --el-card-padding: 10px !important;  // 内边距
  white-space: normal !important; // 自动换行
  overflow-y: scroll !important; // 垂直溢出滚动
}

</style>